package phoenix.web.test_objects;

import org.testng.TestException;
import phoenix.core.PhoenixManager;
import phoenix.core.base.extensions.TestBaseWebExt;
import phoenix.core.data_models.PriceLinkDataModel;
import phoenix.core.data_models.PriceLinkDataModel.CreditsPrices;
import phoenix.core.data_models.TestUserDataModel;
import phoenix.core.data_models.UserProfileDataModel.PaymentDetails;
import phoenix.web.test_objects.data_providers.PaymentDataProviders;

/**
 * Class contains test methods for Payment page
 */
public class PaymentTests extends TestBaseWebExt
{
	public PaymentTests(PhoenixManager p_phoenix)
	{
		super(p_phoenix);
	}

	// Data
	public PaymentDataProviders dataProviders = new PaymentDataProviders(manager);

	/**
	 * Payment package test
	 * @param p_details
	 * @param p_expected
	 */
	public void paymentPackageTest(PaymentDetails p_details, boolean p_expected)
	{
		try
		{
			wd().openAutologin(testUser());
			wd().openPage("/pay");
			page().paymentPage().waitForPageLoad();

			if (manager.isFGF())
			{
				page().paymentPage().selectPaymentCredits();
			}
			else
			{
				page().paymentPage().selectPaymentPackage();
			}

			page().paymentPage().setMainData(p_details);

			if (page().paymentPage().isExtendedBlockDisplayed())
			{
				page().paymentPage().setExtendedData(p_details);
			}

			page().paymentPage().clickSubmitForm();

			if (p_expected)
			{
				page().paymentPage().waitForFeaturesPagePresence();
				page().paymentPage().clickBackToSite();

				if (!manager.isFGF())
				{
					if (!page().paymentPage().isPaymentSuccessfulPopupDisplayed())
					{
						log().errorAndScreen("Payment successful popup isn't displayed");
					}
					else
					{
						page().paymentPage().clickCloseSuccessfulPopup();
					}
				}

				wd().wait(30);
				manager.backend().searchPage().checkPayStatus(1, testUser().getId());
				db().updateUserData(testUser());
			}
			else
			{
				page().paymentPage().waitForFailedPagePresence();
				manager.testUser().setMembershipStatus(testUser().defineMembershipStatus(manager.testUser().getGender()));
			}
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("paymentPackageTest: " + testType(p_expected) + p_ex.toString());
		}

		test().forErrors();
	}

	/**
	 * Payment features test
	 * @param p_details
	 * @param p_expected
	 */
	public void paymentFeaturesTest(PaymentDetails p_details, boolean p_expected)
	{
		try
		{
			if (testUser().getMembershipStatus() > 1)
			{
				throw new TestException(testUser().getId() + " is already has features");
			}

			wd().openAutologin(testUser());
			wd().openPage("/pay/features");
			page().paymentPage().waitForPageLoad();

			int p_permissoin = page().paymentPage().selectPaymentFeatures();

			if (!page().paymentPage().isMainBlockDisplayed())
			{
				page().paymentPage().clickChangePaymentDetails();
			}

			page().paymentPage().setMainData(p_details);

			if (page().paymentPage().isExtendedBlockDisplayed())
			{
				page().paymentPage().setExtendedData(p_details);
			}

			page().paymentPage().clickSubmitForm();

			if (p_expected)
			{
				if (!page().paymentPage().isPaymentSuccessfulPopupDisplayed())
				{
					log().errorAndScreen("Payment successful popup isn't displayed");
				}
				else
				{
					page().paymentPage().clickCloseSuccessfulPopup();
				}
				wd().wait(30);
				manager.backend().searchPage().checkPayStatus(p_permissoin, testUser().getId());
				db().updateUserData(testUser());
			}
			else
			{
				page().paymentPage().waitForFailedPagePresence();
				manager.testUser().setMembershipStatus(testUser().defineMembershipStatus(manager.testUser().getGender()));
			}
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("paymentFeaturesTest: " + testType(p_expected) + p_ex.toString());
		}

		test().forErrors();
	}

	/**
	 * Payment features test for FGF
	 */
	public void paymentFeaturesTest()
	{
		try
		{
			wd().openPage("/pay/features");
			page().paymentPage().waitForPageLoad();

			int p_permissoin = page().paymentPage().selectPaymentFeatures();

			page().paymentPage().clickContinue();
			page().paymentPage().waitForSuccessfulPagePresence();
			page().paymentPage().clickGoToSite();

			wd().wait(30);
			manager.backend().searchPage().checkPayStatus(p_permissoin, testUser().getId());
			db().updateUserData(testUser());
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("paymentFeaturesTest: " + p_ex.toString());
		}

		test().forErrors();
	}

	private String testType(boolean p_expected)
	{
		if (p_expected)
		{
			return "[Positive test] ";
		}
		else
		{
			return "[Negative test] ";
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void validateCardNumberTest(String p_cardNumberValue, String p_fieldType, boolean p_expectedResult)
	{

		boolean actual;

		try
		{
			TestUserDataModel testUser = db().getUserByMembershipStatus(testModel().getSiteName(), 0);
			if (!wd().getCurrentUrl().contains("pay"))
			{
				wd().openURL(testUser.getAutologin());
				wd().openPage("/pay");
			}

			wd().refreshPage();

			manager.web().paymentPage().typeCardNumber(p_cardNumberValue);
			manager.web().paymentPage().clickPay();

			actual = manager.web().paymentPage().isValidatedField(p_fieldType);

			test().forEquivalence(actual, p_expectedResult, "Actual [" + actual + "] != Expected [" + p_expectedResult + "]");

		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("validateCardNumberTest:" + p_ex);
		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void validateCardNameTest(String p_cardNameValue, String p_fieldType, boolean p_expectedResult)
	{

		boolean actual;

		try
		{
			TestUserDataModel testUser = db().getUserByMembershipStatus(testModel().getSiteName(), 0);

			if (!wd().getCurrentUrl().contains("pay"))
			{
				wd().openURL(testUser.getAutologin());
				wd().openPage("/pay");
			}

			wd().refreshPage();

			manager.web().paymentPage().typeCardName(p_cardNameValue);
			manager.web().paymentPage().clickPay();

			actual = manager.web().paymentPage().isValidatedField(p_fieldType);

			test().forEquivalence(actual, p_expectedResult, "Actual [" + actual + "] != Expected [" + p_expectedResult + "]");

		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("validateCardNameTest:" + p_ex);
		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void validateCardSecurityCodeTest(String p_cardSecurityCodeValue, String p_fieldType, boolean p_expectedResult)
	{

		boolean actual;

		try
		{
			TestUserDataModel testUser = db().getUserByMembershipStatus(testModel().getSiteName(), 0);

			if (!wd().getCurrentUrl().contains("pay"))
			{
				wd().openURL(testUser.getAutologin());
				wd().openPage("/pay");
			}

			wd().refreshPage();

			manager.web().paymentPage().typeCardSecurityCode(p_cardSecurityCodeValue);
			manager.web().paymentPage().clickPay();

			actual = manager.web().paymentPage().isValidatedField(p_fieldType);

			test().forEquivalence(actual, p_expectedResult, "Actual [" + actual + "] != Expected [" + p_expectedResult + "]");

		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("validateCardCodeTest:" + p_ex);
		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void validateExpiryDateTest(String p_mounthValue, String p_yearValue, String p_fieldType, boolean p_expectedResult)
	{

		boolean actual;

		try
		{
			TestUserDataModel testUser = db().getUserByMembershipStatus(testModel().getSiteName(), 0);

			if (!wd().getCurrentUrl().contains("pay"))
			{
				wd().openURL(testUser.getAutologin());
				wd().openPage("/pay");
			}
			else
			{
				wd().refreshPage();
			}

			manager.web().paymentPage().selectExpiryDate(p_mounthValue, p_yearValue);
			manager.web().paymentPage().clickPay();

			actual = manager.web().paymentPage().isValidatedField(p_fieldType);

			test().forEquivalence(actual, p_expectedResult, "Actual [" + actual + "] != Expected [" + p_expectedResult + "]");

		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("validateCardExpiryDateTest:" + p_ex);
		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void checkPricesOnPP1(PriceLinkDataModel prices)
	{
		try
		{
			TestUserDataModel user = db().getUserByMembershipStatus(testModel().getSiteName(), 0);
			manager.backend().searchPage().verifyPayStatus(user);
			wd().openURL(user.getAutologin());
			wd().openPage("/pay");
			manager.web().paymentPage().getPackagePrices(prices);
			manager.backend().indexPage().login();
			manager.backend().pricePage().getPackagePrices(prices);
			comparePackagePrices(prices);
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("checkPricesOnPP1" + p_ex.toString());

		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	public void checkPricesOnFeatures(PriceLinkDataModel p_price)
	{
		try
		{
			TestUserDataModel user = db().getUserByMembershipStatus(testModel().getSiteName(), 1);
			manager.backend().searchPage().verifyPayStatus(user);
			wd().openURL(user.getAutologin());
			wd().openPage("/pay");
			manager.web().paymentPage().getFeaturesPrices(p_price);
			manager.backend().indexPage().login();
			manager.backend().pricePage().getFeaturesPrices(p_price);
			compareFeaturesPrices(p_price);
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("checkPricesOnPP1" + p_ex.toString());

		}
		finally
		{
			// Verifying result
			test().forErrors();
		}

	}

	/**
	 * TODO need refactoring
	 */
	private void comparePackagePrices(PriceLinkDataModel p_prices)
	{
		log().info("Check price 3D package...");

		test().assertEquals(p_prices.getActual3dPrice(), p_prices.getExpected3dPrice(), "Actual 3D price != Expected 3D price");

		log().info("Check price 1M package...");

		test().assertEquals(p_prices.getActual1mPrice(), p_prices.getExpected1mPrice(), "Actual 1M price != Expected 1M price");

		log().info("Check price 3M package...");

		test().assertEquals(p_prices.getActual3mPrice(), p_prices.getExpected3mPrice(), "Actual 3M price != Expected 3M price");

		log().info("Check price 6M package...");

		test().assertEquals(p_prices.getActual6mPrice(), p_prices.getExpected6mPrice(), "Actual 6M price != Expected 6M price");

	}

	/**
	 * TODO need refactoring
	 */
	private void compareFeaturesPrices(PriceLinkDataModel p_prices)
	{
		log().info("Check price vip_in_search package...");

		test().assertEquals(p_prices.getActualVipPrice(), p_prices.getExpectedVipPrice(), "Actual vip_in_search price != Expected vip_in_search price");

		log().info("Check price free_communicate_gbr_backend_link package...");

		test().assertEquals(p_prices.getActualFreeCommunicatePrice(), p_prices.getExpectedFreeCommunicatePrice(),
			"Actual free_communicate_gbr_backend_link price != Expected free_communicate_gbr_backend_link price");

		log().info("Check price full_upgrade_gbr_backend_link package...");

		test().assertEquals(p_prices.getActualFullUpgradePrice(), p_prices.getExpectedFullUpgradePrice(),
			"Actual full_upgrade_gbr_backend_link price != Expected full_upgrade_gbr_backend_link price");
	}

	/**
	 * TODO need refactoring
	 */
	public void checkCredits(CreditsPrices prices)
	{
		try
		{
			TestUserDataModel user = db().getUserByMembershipStatus(testModel().getSiteName(), 0);
			wd().openURL(user.getAutologin());
			wd().openPage("/pay");
			manager.web().paymentPage().getCredits(prices);
			manager.backend().indexPage().login();
			manager.backend().pricePage().getCreditsExpected(prices);
			compareCredits(prices);
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("checkPricesOnPP1" + p_ex.toString());

		}
		finally
		{
			// Verifying result
			test().forErrors();
		}
	}

	/**
	 * TODO need refactoring
	 */
	private void compareCredits(CreditsPrices p_prices)
	{
		log().info("Check price 20 credits...");

		test().assertEquals(p_prices.getActual20(), p_prices.getExpected20(), "Actual 20 credits != Expected 20 credits");

		log().info("Check price 40 credits...");

		test().assertEquals(p_prices.getActual40(), p_prices.getExpected40(), "Actual 40 credits != Expected 40 credits");

		log().info("Check price 80 credits...");

		test().assertEquals(p_prices.getActual80(), p_prices.getExpected80(), "Actual 80 credits != Expected 80 credits");

		log().info("Check price 160 credits...");

		test().assertEquals(p_prices.getActual160(), p_prices.getExpected160(), "Actual 160 credits != Expected 160 credits");

		log().info("Check price 320 credits...");

		test().assertEquals(p_prices.getActual320(), p_prices.getExpected320(), "Actual 320 credits != Expected 320 credits");

		log().info("Check price 500 credits...");

		test().assertEquals(p_prices.getActual500(), p_prices.getExpected500(), "Actual 500 credits != Expected 500 credits");

		log().info("Check price 1000 credits...");

		test().assertEquals(p_prices.getActual1000(), p_prices.getExpected1000(), "Actual 1000 credits != Expected 1000 credits");
	}

	public void paymentAuthorizationTest(PaymentDetails p_details)
	{
		try
		{
			page().paymentPage().setPaymentAuthorizationData(p_details);
			page().paymentPage().clickSubmitAuthorization();
			page().paymentPage().waitForSuccessAuthorizationPopup();
			page().paymentPage().clickContinueAuthorizationPopup();
		}
		catch (Exception p_ex)
		{
			log().errorAndScreen("paymentAuthorizationTest: " + p_ex.toString());
		}

		test().forErrors();
	}
}
